{
  "cells": [
    {
      "metadata": {
        "id": "-n3Rngfddxii"
      },
      "cell_type": "markdown",
      "source": [
        "This notebook is a basic tutorial that demonstrates how to configure a simulation using Concordia."
      ]
    },
    {
      "metadata": {
        "id": "T6qSDTZtdeXk"
      },
      "cell_type": "markdown",
      "source": [
        "<a href=\"https://colab.research.google.com/github/google-deepmind/concordia/blob/main/examples/selling_cookies.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "metadata": {
        "id": "o4NhU-Z6cbop"
      },
      "cell_type": "code",
      "source": [
        "# @title Colab-specific setup (use a CodeSpace to avoid the need for this).\n",
        "try:\n",
        "  %env COLAB_RELEASE_TAG\n",
        "except:\n",
        "  pass  # Not running in colab.\n",
        "else:\n",
        "  %pip install --ignore-requires-python --requirement 'https://raw.githubusercontent.com/google-deepmind/concordia/main/examples/requirements.in' 'git+https://github.com/google-deepmind/concordia.git#egg=gdm-concordia'\n",
        "  %pip list"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "R8N4hGX5ci_d"
      },
      "cell_type": "code",
      "source": [
        "# @title Imports\n",
        "\n",
        "from collections.abc import Mapping, Sequence\n",
        "from concordia.contrib import language_models as language_model_utils\n",
        "import concordia.prefabs.entity as entity_prefabs\n",
        "import concordia.prefabs.game_master as game_master_prefabs\n",
        "from concordia.prefabs.simulation import generic as simulation\n",
        "from concordia.typing import entity as entity_lib\n",
        "from concordia.typing import prefab as prefab_lib\n",
        "from concordia.typing import scene as scene_lib\n",
        "from concordia.utils import helper_functions\n",
        "from IPython import display\n",
        "import numpy as np\n",
        "import sentence_transformers"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "a9Pb-LdTcOeZ"
      },
      "cell_type": "code",
      "source": [
        "# @title Language Model Selection: provide key or select DISABLE_LANGUAGE_MODEL\n",
        "\n",
        "# By default this colab uses models via an external API so you must provide an\n",
        "# API key. TogetherAI offers open weights models from all sources.\n",
        "\n",
        "API_KEY = ''  # @param {type: 'string'}\n",
        "# See concordia/language_model/utils.py\n",
        "API_TYPE = 'openai'  # e.g. 'together_ai' or 'openai'.\n",
        "MODEL_NAME = (  # for API_TYPE = 'together_ai', we recommend MODEL_NAME = 'google/gemma-3-27b-it'\n",
        "    'gpt-5'\n",
        ")\n",
        "# To debug without spending money on API calls, set DISABLE_LANGUAGE_MODEL=True\n",
        "DISABLE_LANGUAGE_MODEL = False"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "Za2zOpeTci8_"
      },
      "cell_type": "code",
      "source": [
        "# @title Use the selected language model\n",
        "\n",
        "# Note that it is also possible to use local models or other API models,\n",
        "# simply replace this cell with the correct initialization for the model\n",
        "# you want to use.\n",
        "\n",
        "if not DISABLE_LANGUAGE_MODEL and not API_KEY:\n",
        "  raise ValueError('API_KEY is required.')\n",
        "\n",
        "model = language_model_utils.language_model_setup(\n",
        "    api_type=API_TYPE,\n",
        "    model_name=MODEL_NAME,\n",
        "    api_key=API_KEY,\n",
        "    disable_language_model=DISABLE_LANGUAGE_MODEL,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "KC0dbTwLci6k"
      },
      "cell_type": "code",
      "source": [
        "# @title Setup sentence encoder\n",
        "\n",
        "if DISABLE_LANGUAGE_MODEL:\n",
        "  embedder = lambda _: np.ones(3)\n",
        "else:\n",
        "  st_model = sentence_transformers.SentenceTransformer(\n",
        "      'sentence-transformers/all-mpnet-base-v2'\n",
        "  )\n",
        "  embedder = lambda x: st_model.encode(x, show_progress_bar=False)"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "yN8NEgajci3_"
      },
      "cell_type": "code",
      "source": [
        "test = model.sample_text(\n",
        "    'Is societal and technological progress like getting a clearer picture of '\n",
        "    'something true and deep?'\n",
        ")\n",
        "print(test)"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "Ya7BvCG1cwNY"
      },
      "cell_type": "code",
      "source": [
        "# @title Load prefabs from packages to make the specific palette to use here.\n",
        "\n",
        "prefabs = {\n",
        "    **helper_functions.get_package_classes(entity_prefabs),\n",
        "    **helper_functions.get_package_classes(game_master_prefabs),\n",
        "}"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "TSB7w33mRMOj"
      },
      "cell_type": "code",
      "source": [
        "# @title Print menu of prefabs\n",
        "\n",
        "display.display(\n",
        "    display.Markdown(helper_functions.print_pretty_prefabs(prefabs))\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "X1v6kQQfUGZu"
      },
      "cell_type": "markdown",
      "source": [
        "# Two Friends Catching Up"
      ]
    },
    {
      "metadata": {
        "id": "9wf0JGYWUJj-"
      },
      "cell_type": "code",
      "source": [
        "instances = [\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='conversational__Entity',\n",
        "        role=prefab_lib.Role.ENTITY,\n",
        "        params={\n",
        "            'name': 'Jessica',\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='conversational__Entity',\n",
        "        role=prefab_lib.Role.ENTITY,\n",
        "        params={\n",
        "            'name': 'Chloe',\n",
        "            'conversation_style': (\n",
        "                'Speaks with a lot of energy and excitement. Uses casual, '\n",
        "                'modern language and slang common for a Southern California '\n",
        "                'girl in their mid-20s.'\n",
        "            ),\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='dialogic__GameMaster',\n",
        "        role=prefab_lib.Role.GAME_MASTER,\n",
        "        params={\n",
        "            'name': 'conversation rules',\n",
        "            'next_game_master_name': 'conversation rules',\n",
        "            'acting_order': 'fixed',\n",
        "            'can_terminate_simulation': False,\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='formative_memories_initializer__GameMaster',\n",
        "        role=prefab_lib.Role.INITIALIZER,\n",
        "        params={\n",
        "            'name': 'initial setup rules',\n",
        "            'next_game_master_name': 'conversation rules',\n",
        "            # Shared memory establishes the immediate context for their meeting.\n",
        "            'shared_memories': [\n",
        "                (\n",
        "                    'Jessica and Chloe are best friends from college meeting at'\n",
        "                    ' their favorite coffee shop to catch up after not seeing'\n",
        "                    ' each other for months.'\n",
        "                ),\n",
        "            ],\n",
        "            # Player-specific memories give them individual things to talk about.\n",
        "            'player_specific_memories': {\n",
        "                'Jessica': [\n",
        "                    (\n",
        "                        'Recently got a big promotion at her marketing job and'\n",
        "                        ' is thinking about moving in with her boyfriend.'\n",
        "                    ),\n",
        "                ],\n",
        "                'Chloe': [\n",
        "                    (\n",
        "                        'Just got back from a whirlwind backpacking trip'\n",
        "                        ' through Europe and has tons of stories to share.'\n",
        "                    ),\n",
        "                ],\n",
        "            },\n",
        "        },\n",
        "    ),\n",
        "]"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "kvvKHUUZURFd"
      },
      "cell_type": "code",
      "source": [
        "config = prefab_lib.Config(\n",
        "    default_premise=(\n",
        "        'Two people friends over coffee to discuss their lives and catch up'\n",
        "    ),\n",
        "    default_max_steps=20,\n",
        "    prefabs=prefabs,\n",
        "    instances=instances,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "CcQ4uUlMUV46"
      },
      "cell_type": "code",
      "source": [
        "# @title Initialize the simulation\n",
        "runnable_simulation = simulation.Simulation(\n",
        "    config=config,\n",
        "    model=model,\n",
        "    embedder=embedder,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "HczYKYKsUXSP"
      },
      "cell_type": "code",
      "source": [
        "# @title Run the simulation\n",
        "raw_log = []\n",
        "results_log = runnable_simulation.play(\n",
        "    max_steps=10,\n",
        "    raw_log=raw_log,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "oQvo3alwdMgE"
      },
      "cell_type": "code",
      "source": [
        "# @title Display the log\n",
        "display.HTML(results_log)"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "KoFQJH7OUaWu"
      },
      "cell_type": "markdown",
      "source": [
        "# Love Island First Date"
      ]
    },
    {
      "metadata": {
        "id": "mEDDc_7iUcrs"
      },
      "cell_type": "code",
      "source": [
        "PLAYER_ONE = 'Cody'\n",
        "PLAYER_TWO = 'Megan'\n",
        "\n",
        "instances = [\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='conversational__Entity',\n",
        "        role=prefab_lib.Role.ENTITY,\n",
        "        params={\n",
        "            'name': PLAYER_ONE,\n",
        "            'conversation_style': (\n",
        "                'Talk like a charismatic and flirty stud from Miami.'\n",
        "            ),\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='conversational__Entity',\n",
        "        role=prefab_lib.Role.ENTITY,\n",
        "        params={\n",
        "            'name': PLAYER_TWO,\n",
        "            'conversation_style': (\n",
        "                'Talk like a stereotypical Love Island bombshell from Sussex.'\n",
        "            ),\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='dialogic__GameMaster',\n",
        "        role=prefab_lib.Role.GAME_MASTER,\n",
        "        params={\n",
        "            'name': 'conversation rules',\n",
        "            'next_game_master_name': 'conversation rules',\n",
        "            'acting_order': 'fixed',\n",
        "            'can_terminate_simulation': False,\n",
        "        },\n",
        "    ),\n",
        "    prefab_lib.InstanceConfig(\n",
        "        prefab='formative_memories_initializer__GameMaster',\n",
        "        role=prefab_lib.Role.INITIALIZER,\n",
        "        params={\n",
        "            'name': 'initial setup rules',\n",
        "            'next_game_master_name': 'conversation rules',\n",
        "            'player_specific_memories': {\n",
        "                PLAYER_ONE: [\n",
        "                    'Is a confident personal trainer from Miami, USA.',\n",
        "                    'He is on a first date in the Love Island villa.',\n",
        "                    'He thinks English girls are \"unreal\".',\n",
        "                ],\n",
        "                PLAYER_TWO: [\n",
        "                    'Is a classic \"bombshell\" from Sussex.',\n",
        "                    'She is on a first date in the Love Island villa.',\n",
        "                    'She is not afraid to \"step on toes\" to find her man.',\n",
        "                ],\n",
        "            },\n",
        "        },\n",
        "    ),\n",
        "]\n",
        "\n",
        "config = prefab_lib.Config(\n",
        "    default_premise=(\n",
        "        'Night has fallen on the Love Island villa. The iconic fire pit is '\n",
        "        f'lit, casting a warm glow. {PLAYER_ONE} and {PLAYER_TWO} are sat on '\n",
        "        'the curved sofa around the fire, drinks in hand. The other islanders '\n",
        "        'are out of earshot, giving them their first chance to properly graft.'\n",
        "    ),\n",
        "    default_max_steps=60,\n",
        "    prefabs=prefabs,\n",
        "    instances=instances,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "EeKsufa8Ui_z"
      },
      "cell_type": "code",
      "source": [
        "# @title Initialize the simulation\n",
        "runnable_simulation = simulation.Simulation(\n",
        "    config=config,\n",
        "    model=model,\n",
        "    embedder=embedder,\n",
        ")"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "j8VaF9_FUkNX"
      },
      "cell_type": "code",
      "source": [
        "# @title Run the simulation\n",
        "raw_log = []\n",
        "results_log = runnable_simulation.play(max_steps=10, raw_log=raw_log)"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "Xq59QSi9UlLT"
      },
      "cell_type": "code",
      "source": [
        "# @title Display the log\n",
        "display.HTML(results_log)"
      ],
      "outputs": [],
      "execution_count": null
    },
    {
      "metadata": {
        "id": "S8TdyvoYdSV8"
      },
      "cell_type": "markdown",
      "source": [
        "```\n",
        "Copyright 2025 DeepMind Technologies Limited.\n",
        "\n",
        "Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "you may not use this file except in compliance with the License.\n",
        "You may obtain a copy of the License at\n",
        "\n",
        "    https://www.apache.org/licenses/LICENSE-2.0\n",
        "\n",
        "Unless required by applicable law or agreed to in writing, software\n",
        "distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "See the License for the specific language governing permissions and\n",
        "limitations under the License.\n",
        "```"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "private_outputs": true,
      "provenance": [],
      "toc_visible": true
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
